"""
需求相关的数据传输对象(DTO)定义
用于 API 请求和响应的数据模型
"""
from datetime import datetime
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field, validator
from app.models.base import PyObjectId
from app.models.requirement import (
    RequirementPriority,
)
# RequirementType 和 RequirementSource 已移除，改为使用统一配置管理

# ========== 评论相关 Schema ==========
class RequirementCommentCreate(BaseModel):
    """创建需求评论模型"""
    content: str = Field(..., min_length=1, max_length=2000, description="评论内容")
    parent_id: Optional[str] = Field(None, description="父评论ID，用于回复")
    status: Optional[str] = Field(None, description="评论状态（动态状态，默认为已发布）")

class RequirementCommentUpdate(BaseModel):
    """更新需求评论模型"""
    content: Optional[str] = Field(None, min_length=1, max_length=2000, description="评论内容")
    status: Optional[str] = Field(None, description="评论状态（动态状态）")

class RequirementComment(BaseModel):
    """需求评论"""
    id: str = Field(..., description="评论ID")
    user_id: str = Field(..., description="用户ID")
    user_name: str = Field(..., description="用户名称")
    content: str = Field(..., description="评论内容")
    parent_id: Optional[str] = Field(None, description="父评论ID，用于回复")
    status: str = Field(default="published", description="评论状态（动态状态）")
    is_deleted: bool = Field(default=False, description="是否已删除（已废弃，使用status字段）")
    created_at: datetime = Field(default_factory=datetime.utcnow, description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")
    deleted_at: Optional[datetime] = Field(None, description="删除时间")

# ========== 附件相关 Schema ==========
class RequirementAttachment(BaseModel):
    """需求附件"""
    id: str = Field(..., description="附件ID")
    filename: str = Field(..., description="文件名")
    original_filename: str = Field(..., description="原始文件名")
    file_size: int = Field(..., description="文件大小")
    file_type: str = Field(..., description="文件类型")
    url: str = Field(..., description="文件URL")
    uploaded_by: str = Field(..., description="上传者ID")
    uploaded_at: datetime = Field(default_factory=datetime.utcnow, description="上传时间")

# ========== 依赖关系相关 Schema ==========
class RequirementDependency(BaseModel):
    """需求依赖关系"""
    requirement_id: str = Field(..., description="依赖的需求ID")
    dependency_type: str = Field(..., description="依赖类型: blocks, depends_on, relates_to")
    description: Optional[str] = Field(None, description="依赖描述")

class RequirementDependencyCreate(BaseModel):
    """创建需求依赖模型"""
    requirement_id: str = Field(..., description="依赖的需求ID")
    dependency_type: str = Field(..., description="依赖类型")
    description: Optional[str] = Field(None, max_length=500, description="依赖描述")

class RequirementDependencyUpdate(BaseModel):
    """更新需求依赖模型"""
    dependency_type: Optional[str] = Field(None, description="依赖类型")
    description: Optional[str] = Field(None, max_length=500, description="依赖描述")

# ========== 创建和更新 Schema ==========
class RequirementCreate(BaseModel):
    """创建需求模型"""
    title: str = Field(..., min_length=1, max_length=200, description="需求标题")
    description: Optional[str] = Field(None, max_length=100000, description="需求描述")
    requirement_type: str = Field(default="functional", description="需求类型（从类型管理获取）")
    status: str = Field(default="", description="需求状态（从状态管理系统动态获取，创建时使用默认状态）")
    priority: RequirementPriority = Field(default=RequirementPriority.MEDIUM, description="需求优先级")
    source: str = Field(default="internal", description="需求来源（从来源管理获取）")
    project_id: PyObjectId = Field(..., description="所属项目ID")
    assignee_id: Optional[PyObjectId] = Field(None, description="负责人ID")
    reporter_id: PyObjectId = Field(..., description="报告人ID")
    acceptance_criteria: Optional[str] = Field(None, max_length=5000, description="验收标准")
    business_value: Optional[str] = Field(None, max_length=2000, description="业务价值")
    estimated_effort: Optional[float] = Field(None, ge=0, description="预估工作量(人天)")
    actual_effort: Optional[float] = Field(None, ge=0, description="实际工作量(人天)")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    tags: List[str] = Field(default_factory=list, description="需求标签")
    parent_id: Optional[str] = Field(None, description="父需求ID，用于构建树形结构")
    sort_order: int = Field(default=0, description="排序顺序")
    
    @validator('due_date')
    def validate_due_date(cls, v, values):
        if v and 'start_date' in values and values['start_date'] and v < values['start_date']:
            raise ValueError('截止日期不能早于开始日期')
        return v

class RequirementUpdate(BaseModel):
    """更新需求模型"""
    title: Optional[str] = Field(None, min_length=1, max_length=200, description="需求标题")
    description: Optional[str] = Field(None, max_length=100000, description="需求描述")
    requirement_type: Optional[str] = Field(None, description="需求类型（从类型管理获取）")
    status: Optional[str] = Field(None, description="需求状态")
    priority: Optional[RequirementPriority] = Field(None, description="需求优先级")
    source: Optional[str] = Field(None, description="需求来源（从来源管理获取）")
    project_id: Optional[PyObjectId] = Field(None, description="所属项目ID")
    assignee_id: Optional[PyObjectId] = Field(None, description="负责人ID")
    reporter_id: Optional[PyObjectId] = Field(None, description="报告人ID")
    acceptance_criteria: Optional[str] = Field(None, max_length=5000, description="验收标准")
    business_value: Optional[str] = Field(None, max_length=2000, description="业务价值")
    estimated_effort: Optional[float] = Field(None, ge=0, description="预估工作量(人天)")
    actual_effort: Optional[float] = Field(None, ge=0, description="实际工作量(人天)")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    tags: Optional[List[str]] = Field(None, description="需求标签")
    parent_id: Optional[str] = Field(None, description="父需求ID，用于构建树形结构")
    sort_order: Optional[int] = Field(None, description="排序顺序")
    
    @validator('due_date')
    def validate_due_date(cls, v, values):
        if v and 'start_date' in values and values['start_date'] and v < values['start_date']:
            raise ValueError('截止日期不能早于开始日期')
        return v

# ========== 响应 Schema ==========
class RequirementResponse(BaseModel):
    """需求响应模型"""
    id: str = Field(..., description="需求ID")
    title: str = Field(..., description="需求标题")
    description: Optional[str] = Field(None, description="需求描述")
    requirement_type: str = Field(..., description="需求类型（从类型管理获取）")
    status: str = Field(..., description="需求状态")
    priority: RequirementPriority = Field(..., description="需求优先级")
    source: str = Field(..., description="需求来源（从来源管理获取）")
    project_id: str = Field(..., description="所属项目ID")
    project_name: Optional[str] = Field(None, description="项目名称")
    assignee_id: Optional[str] = Field(None, description="负责人ID")
    assignee_name: Optional[str] = Field(None, description="负责人姓名")
    reporter_id: str = Field(..., description="报告人ID")
    reporter_name: Optional[str] = Field(None, description="报告人姓名")
    updated_by_id: Optional[str] = Field(None, description="最后更新人ID")
    updated_by_name: Optional[str] = Field(None, description="最后更新人姓名")
    acceptance_criteria: Optional[str] = Field(None, description="验收标准")
    business_value: Optional[str] = Field(None, description="业务价值")
    estimated_effort: Optional[float] = Field(None, description="预估工作量(人天)")
    actual_effort: Optional[float] = Field(None, description="实际工作量(人天)")
    start_date: Optional[datetime] = Field(None, description="开始日期")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    tags: List[str] = Field(default_factory=list, description="需求标签")
    comments: List[RequirementComment] = Field(default_factory=list, description="需求评论")
    attachments: List[RequirementAttachment] = Field(default_factory=list, description="需求附件")
    dependencies: List[RequirementDependency] = Field(default_factory=list, description="需求依赖")
    watchers: List[str] = Field(default_factory=list, description="关注者ID列表")
    versions: Optional[List[Dict[str, Any]]] = Field(default_factory=list, description="关联的版本列表")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    approved_at: Optional[datetime] = Field(None, description="批准时间")
    implemented_at: Optional[datetime] = Field(None, description="实现时间")
    
    # 树形结构字段
    parent_id: Optional[str] = Field(None, description="父需求ID")
    sort_order: int = Field(default=0, description="排序顺序")
    children: List['RequirementResponse'] = Field(default_factory=list, description="子需求列表")
    children_count: int = Field(default=0, description="子需求数量")
    
    # 计算字段
    is_overdue: Optional[bool] = Field(None, description="是否逾期")
    progress: Optional[float] = Field(None, description="需求进度百分比")
    related_tasks_count: Optional[int] = Field(None, description="关联任务数量")
    completed_tasks_count: Optional[int] = Field(None, description="已完成任务数量")

class RequirementSummary(BaseModel):
    """需求摘要模型"""
    id: str = Field(..., description="需求ID")
    title: str = Field(..., description="需求标题")
    status: str = Field(..., description="需求状态")
    priority: RequirementPriority = Field(..., description="需求优先级")
    assignee_name: Optional[str] = Field(None, description="负责人姓名")
    due_date: Optional[datetime] = Field(None, description="截止日期")
    is_overdue: bool = Field(..., description="是否逾期")
    progress: float = Field(..., description="需求进度百分比")

# ========== 其他操作 Schema ==========
class RequirementStatusUpdate(BaseModel):
    """需求状态更新模型"""
    status: str = Field(..., description="新状态")
    comment: Optional[str] = Field(None, max_length=500, description="状态变更说明")

class RequirementAssignmentUpdate(BaseModel):
    """需求分配更新模型"""
    assignee_id: Optional[str] = Field(None, description="负责人ID")
    comment: Optional[str] = Field(None, max_length=500, description="分配说明")

class RequirementBulkUpdate(BaseModel):
    """批量更新需求模型"""
    requirement_ids: List[str] = Field(..., min_items=1, description="需求ID列表")
    updates: RequirementUpdate = Field(..., description="更新内容")

# ========== 筛选和统计 Schema ==========
class RequirementFilter(BaseModel):
    """需求筛选模型"""
    status: Optional[List[str]] = Field(None, description="状态筛选")
    priority: Optional[List[RequirementPriority]] = Field(None, description="优先级筛选")
    requirement_type: Optional[List[str]] = Field(None, description="类型筛选（从类型管理获取）")
    source: Optional[List[str]] = Field(None, description="来源筛选（从来源管理获取）")
    assignee_id: Optional[str] = Field(None, description="负责人筛选")
    reporter_id: Optional[str] = Field(None, description="报告人筛选")
    project_id: Optional[str] = Field(None, description="项目筛选")
    tags: Optional[List[str]] = Field(None, description="标签筛选")
    due_date_range: Optional[Dict[str, datetime]] = Field(None, description="截止日期范围筛选")
    created_date_range: Optional[Dict[str, datetime]] = Field(None, description="创建日期范围筛选")
    is_overdue: Optional[bool] = Field(None, description="是否逾期筛选")

class RequirementStats(BaseModel):
    """需求统计模型"""
    total_requirements: int = Field(..., description="需求总数")
    approved_requirements: int = Field(..., description="已批准需求数")
    implemented_requirements: int = Field(..., description="已实现需求数")
    overdue_requirements: int = Field(..., description="逾期需求数")
    requirements_by_status: Dict[str, int] = Field(..., description="按状态分组的需求数")
    requirements_by_priority: Dict[str, int] = Field(..., description="按优先级分组的需求数")
    requirements_by_type: Dict[str, int] = Field(..., description="按类型分组的需求数")
    requirements_by_source: Dict[str, int] = Field(..., description="按来源分组的需求数")

# ========== 看板相关 Schema ==========
class RequirementBoard(BaseModel):
    """需求看板模型"""
    project_id: str = Field(..., description="项目ID")
    project_name: str = Field(..., description="项目名称")
    columns: Dict[str, List[RequirementSummary]] = Field(..., description="看板列")

class RequirementBoardColumn(BaseModel):
    """需求看板列模型"""
    status: str = Field(..., description="状态")
    title: str = Field(..., description="列标题")
    requirements: List[RequirementSummary] = Field(default_factory=list, description="需求列表")
    requirement_count: int = Field(..., description="需求数量")

# ========== 活动记录 Schema ==========
class RequirementActivity(BaseModel):
    """需求活动记录模型"""
    id: str = Field(..., description="活动ID")
    requirement_id: str = Field(..., description="需求ID")
    user_id: str = Field(..., description="用户ID")
    user_name: str = Field(..., description="用户名称")
    action: str = Field(..., description="操作类型")
    description: str = Field(..., description="操作描述")
    old_value: Optional[str] = Field(None, description="旧值")
    new_value: Optional[str] = Field(None, description="新值")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="元数据")
    created_at: datetime = Field(..., description="创建时间")

# 延迟导入以支持递归模型
RequirementResponse.model_rebuild()

